/*! * jQuery Smart Banner * Copyright (c) 2012 Arnold Daniels * Based on 'jQuery Smart Web App Banner' by Kurt Zenisek @ kzeni.com */ !function ($) { var SmartBanner = function (options) { this.origHtmlMargin = parseFloat($('html').css('margin-top')) // Get the original margin-top of the HTML element so we can take that into account this.options = $.extend({}, $.smartbanner.defaults, options) var standalone = navigator.standalone // Check if it's already a standalone web app or running within a webui view of an app (not mobile safari) , UA = navigator.userAgent // Detect banner type (iOS or Android) if (this.options.force) { this.type = this.options.force } else if (UA.match(/iPhone|iPod/i) != null || (UA.match(/iPad/) && this.options.iOSUniversalApp)) { if (UA.match(/Safari/i) != null && (UA.match(/CriOS/i) != null || window.Number(UA.substr(UA.indexOf('OS ') + 3, 3).replace('_', '.')) < 6)) this.type = 'ios' // Check webview and native smart banner support (iOS 6+) } else if (UA.match(/\bSilk\/(.*\bMobile Safari\b)?/) || UA.match(/\bKF\w/) || UA.match('Kindle Fire')) { this.type = 'kindle' } else if (UA.match(/Android/i) != null) { this.type = 'android' } else if (UA.match(/Windows NT 6.2/i) != null && UA.match(/Touch/i) !== null) { this.type = 'windows' } // Don't show banner if device isn't iOS or Android, website is loaded in app or user dismissed banner if (!this.type || standalone || this.getCookie('sb-closed') || this.getCookie('sb-installed')) { return } // Calculate scale this.scale = this.options.scale == 'auto' ? $(window).width() / window.screen.width : this.options.scale if (this.scale < 1) this.scale = 1 // Get info from meta data var meta = $(this.type == 'android' ? 'meta[name="google-play-app"]' : this.type == 'ios' ? 'meta[name="apple-itunes-app"]' : this.type == 'kindle' ? 'meta[name="kindle-fire-app"]' : 'meta[name="msApplication-ID"]'); if (meta.length == 0) return // For Windows Store apps, get the PackageFamilyName for protocol launch if (this.type == 'windows') { this.pfn = $('meta[name="msApplication-PackageFamilyName"]').attr('content'); this.appId = meta.attr('content')[1] } else { this.appId = /app-id=([^\s,]+)/.exec(meta.attr('content'))[1] } this.title = this.options.title ? this.options.title : meta.data('title') || $('title').text().replace(/\s*[|\-ยท].*$/, '') this.author = this.options.author ? this.options.author : meta.data('author') || ($('meta[name="author"]').length ? $('meta[name="author"]').attr('content') : window.location.hostname) this.iconUrl = meta.data('icon-url'); this.price = meta.data('price'); // Create banner this.create() this.show() this.listen() } SmartBanner.prototype = { constructor: SmartBanner , create: function() { var iconURL , link=(this.options.url ? this.options.url : (this.type == 'windows' ? 'ms-windows-store:PDP?PFN=' + this.pfn : (this.type == 'android' ? 'market://details?id=' : (this.type == 'kindle' ? 'amzn://apps/android?asin=' : 'https://itunes.apple.com/' + this.options.appStoreLanguage + '/app/id'))) + this.appId) , price = this.price || this.options.price , inStore=price ? price + ' - ' + (this.type == 'android' ? this.options.inGooglePlay : this.type == 'kindle' ? this.options.inAmazonAppStore : this.type == 'ios' ? this.options.inAppStore : this.options.inWindowsStore) : '' , gloss=this.options.iconGloss === null ? (this.type=='ios') : this.options.iconGloss if(this.options.url) link = this.options.url else { if(this.type=='android') { link = 'market://details?id=' + this.appId if(this.options.GooglePlayParams) link = link + '&referrer=' + this.options.GooglePlayParams } else link = 'https://itunes.apple.com/' + this.options.appStoreLanguage + '/app/id' + this.appId } var banner = '
×
'+this.title+''+this.author+''+inStore+'
'+this.options.button+'
'; (this.options.layer) ? $(this.options.appendToSelector).append(banner) : $(this.options.appendToSelector).prepend(banner); if (this.options.icon) { iconURL = this.options.icon } else if(this.iconUrl) { iconURL = this.iconUrl; } else if ($('link[rel="apple-touch-icon-precomposed"]').length > 0) { iconURL = $('link[rel="apple-touch-icon-precomposed"]').attr('href') if (this.options.iconGloss === null) gloss = false } else if ($('link[rel="apple-touch-icon"]').length > 0) { iconURL = $('link[rel="apple-touch-icon"]').attr('href') } else if ($('meta[name="msApplication-TileImage"]').length > 0) { iconURL = $('meta[name="msApplication-TileImage"]').attr('content') } else if ($('meta[name="msapplication-TileImage"]').length > 0) { /* redundant because ms docs show two case usages */ iconURL = $('meta[name="msapplication-TileImage"]').attr('content') } if (iconURL) { $('#smartbanner .sb-icon').css('background-image','url('+iconURL+')') if (gloss) $('#smartbanner .sb-icon').addClass('gloss') } else{ $('#smartbanner').addClass('no-icon') } this.bannerHeight = $('#smartbanner').outerHeight() + 2 if (this.scale > 1) { $('#smartbanner') .css('top', parseFloat($('#smartbanner').css('top')) * this.scale) .css('height', parseFloat($('#smartbanner').css('height')) * this.scale) .hide() $('#smartbanner .sb-container') .css('-webkit-transform', 'scale('+this.scale+')') .css('-msie-transform', 'scale('+this.scale+')') .css('-moz-transform', 'scale('+this.scale+')') .css('width', $(window).width() / this.scale) } $('#smartbanner').css('position', (this.options.layer) ? 'absolute' : 'static') } , listen: function () { $('#smartbanner .sb-close').on('click',$.proxy(this.close, this)) $('#smartbanner .sb-button').on('click',$.proxy(this.install, this)) } , show: function(callback) { var banner = $('#smartbanner'); banner.stop(); if (this.options.layer) { banner.animate({top: 0, display: 'block'}, this.options.speedIn).addClass('shown').show(); $('html').animate({marginTop: this.origHtmlMargin + (this.bannerHeight * this.scale)}, this.options.speedIn, 'swing', callback); } else { if ($.support.transition) { banner.animate({top:0},this.options.speedIn).addClass('shown'); var transitionCallback = function() { $('html').removeClass('sb-animation'); if (callback) { callback(); } }; $('html').addClass('sb-animation').one($.support.transition.end, transitionCallback).emulateTransitionEnd(this.options.speedIn).css('margin-top', this.origHtmlMargin+(this.bannerHeight*this.scale)); } else { banner.slideDown(this.options.speedIn).addClass('shown'); } } } , hide: function(callback) { var banner = $('#smartbanner'); banner.stop(); if (this.options.layer) { banner.animate({top: -1 * this.bannerHeight * this.scale, display: 'block'}, this.options.speedIn).removeClass('shown'); $('html').animate({marginTop: this.origHtmlMargin}, this.options.speedIn, 'swing', callback); } else { if ($.support.transition) { banner.css('top', -1*this.bannerHeight*this.scale).removeClass('shown'); var transitionCallback = function() { $('html').removeClass('sb-animation'); if (callback) { callback(); } }; $('html').addClass('sb-animation').one($.support.transition.end, transitionCallback).emulateTransitionEnd(this.options.speedOut).css('margin-top', this.origHtmlMargin); } else { banner.slideUp(this.options.speedOut).removeClass('shown'); } } } , close: function(e) { e.preventDefault() this.hide() this.setCookie('sb-closed','true',this.options.daysHidden); } , install: function(e) { if (this.options.hideOnInstall) { this.hide() } this.setCookie('sb-installed','true',this.options.daysReminder) } , setCookie: function(name, value, exdays) { var exdate = new Date() exdate.setDate(exdate.getDate()+exdays) value=encodeURI(value)+((exdays==null)?'':'; expires='+exdate.toUTCString()) document.cookie=name+'='+value+'; path=/;' } , getCookie: function(name) { var i,x,y,ARRcookies = document.cookie.split(";") for(i=0;i) author: null, // What the author of the app should be in the banner (defaults to or hostname) price: 'FREE', // Price of the app appStoreLanguage: 'us', // Language code for App Store inAppStore: 'On the App Store', // Text of price for iOS inGooglePlay: 'In Google Play', // Text of price for Android inAmazonAppStore: 'In the Amazon Appstore', inWindowsStore: 'In the Windows Store', //Text of price for Windows GooglePlayParams: null, // Aditional parameters for the market icon: null, // The URL of the icon (defaults to ) iconGloss: null, // Force gloss effect for iOS even for precomposed button: 'VIEW', // Text for the install button url: null, // The URL for the button. Keep null if you want the button to link to the app store. scale: 'auto', // Scale based on viewport size (set to 1 to disable) speedIn: 300, // Show animation speed of the banner speedOut: 400, // Close animation speed of the banner daysHidden: 15, // Duration to hide the banner after being closed (0 = always show banner) daysReminder: 90, // Duration to hide the banner after "VIEW" is clicked *separate from when the close button is clicked* (0 = always show banner) force: null, // Choose 'ios', 'android' or 'windows'. Don't do a browser check, just always show this banner hideOnInstall: true, // Hide the banner after "VIEW" is clicked. layer: false, // Display as overlay layer or slide down the page iOSUniversalApp: true, // If the iOS App is a universal app for both iPad and iPhone, display Smart Banner to iPad users, too. appendToSelector: 'body' //Append the banner to a specific selector } $.smartbanner.Constructor = SmartBanner; // ============================================================ // Bootstrap transition // Copyright 2011-2014 Twitter, Inc. // Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) function transitionEnd() { var el = document.createElement('smartbanner') var transEndEventNames = { WebkitTransition: 'webkitTransitionEnd', MozTransition: 'transitionend', OTransition: 'oTransitionEnd otransitionend', transition: 'transitionend' } for (var name in transEndEventNames) { if (el.style[name] !== undefined) { return {end: transEndEventNames[name]} } } return false // explicit for ie8 ( ._.) } if ($.support.transition !== undefined) return // Prevent conflict with Twitter Bootstrap // http://blog.alexmaccaw.com/css-transitions $.fn.emulateTransitionEnd = function(duration) { var called = false, $el = this $(this).one($.support.transition.end, function() { called = true }) var callback = function() { if (!called) $($el).trigger($.support.transition.end) } setTimeout(callback, duration) return this } $(function() { $.support.transition = transitionEnd() }) // ============================================================ }(window.jQuery); ; // calculate the height of the lazy loading placeholder, // to prevent the 'jump' effect when the final image is loaded (function ($) { $(document).ready( function (){ $('.lazy-hidden').each( function() { var aspect_ratio = $(this).data('aspect-ratio'); // we need to get the width of the image's parent element, // as it is what defines the width that the image will have var width = $(this).parent().width(); // we then calculate the height of the placeholder based on the // parent's width and the aspect ratio we got from the uploaded image var height = Math.floor(width / aspect_ratio); $(this).css('height', height); }); }); }(jQuery)); ; /* Lazy Load XT 1.0.5 | MIT License */ !function(a,b,c,d){function e(a,b){return a[b]===d?t[b]:a[b]}function f(){var a=b.pageYOffset;return a===d?r.scrollTop:a}function g(a,b){var c=t["on"+a];c&&(w(c)?c.call(b[0]):(c.addClass&&b.addClass(c.addClass),c.removeClass&&b.removeClass(c.removeClass))),b.trigger("lazy"+a,[b]),k()}function h(b){g(b.type,a(this).off(p,h))}function i(c){if(A.length){c=c||t.forceLoad,B=1/0;var d,e,i=f(),j=b.innerHeight||r.clientHeight,k=b.innerWidth||r.clientWidth;for(d=0,e=A.length;e>d;d++){var l,m=A[d],o=m[0],q=m[n],s=!1,u=c;if(z(r,o)){if(c||!q.visibleOnly||o.offsetWidth||o.offsetHeight){if(!u){var v=o.getBoundingClientRect(),x=q.edgeX,y=q.edgeY;l=v.top+i-y-j,u=i>=l&&v.bottom>-y&&v.left<=k+x&&v.right>-x}if(u){g("show",m);var C=q.srcAttr,D=w(C)?C(m):o.getAttribute(C);D&&(m.on(p,h),o.src=D),s=!0}else B>l&&(B=l)}}else s=!0;s&&(A.splice(d--,1),e--)}e||g("complete",a(r))}}function j(){C>1?(C=1,i(),setTimeout(j,t.throttle)):C=0}function k(a){A.length&&(a&&"scroll"===a.type&&a.currentTarget===b&&B>=f()||(C||setTimeout(j,0),C=2))}function l(){v.lazyLoadXT()}function m(){i(!0)}var n="lazyLoadXT",o="lazied",p="load error",q="lazy-hidden",r=c.documentElement||c.body,s=b.onscroll===d||!!b.operamini||!r.getBoundingClientRect,t={autoInit:!0,selector:"img[data-src]",blankImage:"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",throttle:99,forceLoad:s,loadEvent:"pageshow",updateEvent:"load orientationchange resize scroll touchmove focus",forceEvent:"",oninit:{removeClass:"lazy"},onshow:{addClass:q},onload:{removeClass:q,addClass:"lazy-loaded"},onerror:{removeClass:q},checkDuplicates:!0},u={srcAttr:"data-src",edgeX:0,edgeY:0,visibleOnly:!0},v=a(b),w=a.isFunction,x=a.extend,y=a.data||function(b,c){return a(b).data(c)},z=a.contains||function(a,b){for(;b=b.parentNode;)if(b===a)return!0;return!1},A=[],B=0,C=0;a[n]=x(t,u,a[n]),a.fn[n]=function(c){c=c||{};var d,f=e(c,"blankImage"),h=e(c,"checkDuplicates"),i=e(c,"scrollContainer"),j={};a(i).on("scroll",k);for(d in u)j[d]=e(c,d);return this.each(function(d,e){if(e===b)a(t.selector).lazyLoadXT(c);else{if(h&&y(e,o))return;var i=a(e).data(o,1);f&&"IMG"===e.tagName&&!e.src&&(e.src=f),i[n]=x({},j),g("init",i),A.push(i)}})},a(c).ready(function(){g("start",v),v.on(t.loadEvent,l).on(t.updateEvent,k).on(t.forceEvent,m),a(c).on(t.updateEvent,k),t.autoInit&&l()})}(window.jQuery||window.Zepto||window.$,window,document),function(a){var b=a.lazyLoadXT;b.selector+=",video,iframe[data-src]",b.videoPoster="data-poster",a(document).on("lazyshow","video",function(c,d){var e=d.lazyLoadXT.srcAttr,f=a.isFunction(e);d.attr("poster",d.attr(b.videoPoster)).children("source,track").each(function(b,c){var d=a(c);d.attr("src",f?e(d):d.attr(e))}),this.load()})}(window.jQuery||window.Zepto||window.$);; /** * @file bfi_smart_app_banners.js */ (function ($) { $(document).ready(function() { // don't show the banner if mobile safari is detected, allow the apple smart app banner to do it's thing. if (!(/(iPad|iPhone|iPod).*OS [6-7].*AppleWebKit.*Mobile.*Safari/.test(navigator.userAgent))) { var iconPath = typeof Drupal.settings.bfi_smart_app_banner.bfi_smart_app_banner_google_play_icon != 'undefined' ? Drupal.settings.bfi_smart_app_banner.bfi_smart_app_banner_google_play_icon : null; var appTitle = typeof Drupal.settings.bfi_smart_app_banner.bfi_smart_app_banner_app_title != 'undefined' ? Drupal.settings.bfi_smart_app_banner.bfi_smart_app_banner_app_title : ''; var appPrice = typeof Drupal.settings.bfi_smart_app_banner.bfi_smart_app_banner_app_price != 'undefined' ? Drupal.settings.bfi_smart_app_banner.bfi_smart_app_banner_app_price : 'FREE'; var appURL = typeof Drupal.settings.bfi_smart_app_banner.bfi_smart_app_banner_google_app_url != 'undefined' ? Drupal.settings.bfi_smart_app_banner.bfi_smart_app_banner_google_app_url : null; var appGooglePhone = typeof Drupal.settings.bfi_smart_app_banner.bfi_smart_app_banners_google_app_phone_enable != 'undefined' ? Drupal.settings.bfi_smart_app_banner.bfi_smart_app_banners_google_app_phone_enable : 0; var appGoogleTablet = typeof Drupal.settings.bfi_smart_app_banner.bfi_smart_app_banners_google_app_tablet_enable != 'undefined' ? Drupal.settings.bfi_smart_app_banner.bfi_smart_app_banners_google_app_tablet_enable : 0; if ((appGooglePhone && Modernizr.mq('only screen and (max-width: 767px)') || (appGoogleTablet && Modernizr.mq('only screen and (min-width:768px)')))) { $.smartbanner({ title: appTitle, // What the title of the app should be in the banner (defaults to ) author: ' ', // What the author of the app should be in the banner (defaults to <meta name="author"> or hostname) price: appPrice, // Price of the app appStoreLanguage: 'uk', // Language code for App Store inAppStore: 'On the App Store', // Text of price for iOS inGooglePlay: 'In Google Play', // Text of price for Android icon: iconPath, // The URL of the icon (defaults to <link>) iconGloss: true, // Force gloss effect for iOS even for precomposed (true or false) button: 'VIEW', // Text on the install button scale: 'auto', // Scale based on viewport size (set to 1 to disable) speedIn: 300, // Show animation speed of the banner speedOut: 400, // Close animation speed of the banner daysHidden: 15, // Duration to hide the banner after being closed (0 = always show banner) daysReminder: 90, // Duration to hide the banner after "VIEW" is clicked (0 = always show banner) force: null, // Choose 'ios' or 'android'. Don't do a browser check, just always show this banner layer: true, // Display as overlay layer or slide down the page url: appURL // The URL for the button. Keep null if you want the button to link to the app store. }); } } }); })(jQuery);;